package de.shortys.myhome.api.plugins;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.xml.sax.SAXException;

import de.java.shortys.utils.file.FileUtils;
import de.shortys.myhome.api.controller.AbstractApplication;
import de.shortys.myhome.api.controller.AbstractModule;

public class PluginReader {

	private AbstractApplication application;

	private List<AbstractModule> plugins;

	public List<AbstractModule> getPlugins() {
		return plugins;
	}

	private String filepath;

	{
		plugins = new ArrayList<AbstractModule>();
	}

	public PluginReader(AbstractApplication application, String filepath) throws SAXException, IOException,
			ParserConfigurationException, ClassNotFoundException, JDOMException, InstantiationException,
			IllegalAccessException, SecurityException, IllegalArgumentException, NoSuchMethodException,
			InvocationTargetException {
		this.filepath = filepath;
		this.application = application;
		initialize();
	}

	@SuppressWarnings("unchecked")
	private void initialize() throws SAXException, IOException, ParserConfigurationException, ClassNotFoundException,
			JDOMException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException,
			IllegalArgumentException, InvocationTargetException {
		Document doc = null;

		File f = FileUtils.getFileFromClassPath(getClass().getClassLoader(), filepath);
		SAXBuilder builder = new SAXBuilder();
		doc = builder.build(f);
		Element root = doc.getRootElement();
		for (Element child : (List<Element>) root.getChildren()) {
			final String className = child.getAttributeValue("class");
			Class clazz = Class.forName(className);
			if (AbstractModule.class.isAssignableFrom(clazz)) {
				Constructor constructor = clazz.getConstructor(AbstractApplication.class);
				plugins.add((AbstractModule) constructor.newInstance(new Object[] { application }));
			}
		}
	}
}
